package app.controllers.trade;

import app.Const;
import app.jobs.asyn.CheckAccountJob;
import app.kit.TypeKit;
import app.kits.ReportTplPathKit;
import app.models.order.CheckAccount;
import app.models.order.Order;
import com.google.common.base.MoreObjects;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import goja.StringPool;
import goja.date.DateFormatter;
import goja.mvc.Controller;
import goja.mvc.render.JxlsRender;
import goja.plugins.sqlinxml.SqlKit;
import goja.rapid.datatables.DTCriterias;
import goja.rapid.db.Condition;
import goja.rapid.db.DaoKit;
import goja.security.shiro.Securitys;
import goja.tuples.Quartet;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

import static app.Const.DATE_SPLIT;
import static app.constant.OrderConstant.BUY_TYPE;
import static app.constant.OrderConstant.CHARGING;
import static app.constant.OrderConstant.INC_TYPE;
import static app.constant.OrderConstant.ORDER_STATUS;
import static app.constant.OrderConstant.ORDER_TYPES;
import static app.constant.OrderConstant.ORDRFAIL;
import static app.constant.OrderConstant.PRODUCTFAIL;
import static app.constant.OrderConstant.RPN_TYPE;
import static app.constant.OrderConstant.TFR_PAY_TYPE;
import static app.constant.OrderConstant.TFR_TYPE;
import static app.constant.OrderConstant.WITHDRAWALS;

/**
 * <p>
 * The url trade/reconciliation Controller.
 * 对账单
 * </p>
 *
 * @author sagyf yang
 * @version 1.0
 * @since JDK 1.6
 */
public class ReconciliationController extends Controller {

    /**
     * The index route.
     * the url /trade/reconciliation
     * the view in index.ftl
     */
    public void index() {
    }

    public void dtlist() {
        DTCriterias criterias = getCriterias();
        String time_q = getPara("time");
        if (!Strings.isNullOrEmpty(time_q)) {
            time_q = StringUtils.replace(time_q,StringPool.SLASH, StringPool.EMPTY);
            final String[] times = time_q.split(DATE_SPLIT);
            criterias.setParam("rca.transdate", Condition.BETWEEN, new Object[]{times[0], times[1]});
        }

        renderDataTables(criterias, "checkaccount");
    }


    public void sync() {
        new CheckAccountJob().now();
        renderAjaxSuccess();
    }

    public void stat() {
        String time_q = getPara("time");
        String order_q = getPara("order");
        String type_q = getPara("type");
        final Quartet<BigDecimal, BigDecimal, BigDecimal, BigDecimal> stats = CheckAccount.dao.statByOrderType(time_q, order_q, type_q);
        final List<Order> orderStat = Order.dao.statByOrderType(time_q, order_q, type_q);
        Map<String, BigDecimal> type_amounts = Maps.newHashMap();
        for (Order order : orderStat) {
            type_amounts.put(order.getStr("order_type"), order.getBigDecimal(Const.FIELD_AMOUNT));
        }

        Map<String, Object> results = Maps.newHashMap();
        results.put("bank", stats);
        final BigDecimal chargingAmount = MoreObjects.firstNonNull(type_amounts.get(CHARGING),BigDecimal.ZERO);
        final BigDecimal wdAmount = MoreObjects.firstNonNull(type_amounts.get(WITHDRAWALS),BigDecimal.ZERO);
        final BigDecimal incAmount = MoreObjects.firstNonNull(type_amounts.get(INC_TYPE),BigDecimal.ZERO);
        final BigDecimal rpnAmount = MoreObjects.firstNonNull(type_amounts.get(RPN_TYPE),BigDecimal.ZERO);
        final BigDecimal tfrpayAmount = MoreObjects.firstNonNull(type_amounts.get(TFR_PAY_TYPE),BigDecimal.ZERO);
        final BigDecimal productfailAmount = MoreObjects.firstNonNull(type_amounts.get(PRODUCTFAIL),BigDecimal.ZERO);
        final BigDecimal buyAmount = MoreObjects.firstNonNull(type_amounts.get(BUY_TYPE),BigDecimal.ZERO);
        final BigDecimal tfrAmount = MoreObjects.firstNonNull(type_amounts.get(TFR_TYPE), BigDecimal.ZERO);
        final BigDecimal trfFailAmount = MoreObjects.firstNonNull(type_amounts.get(ORDRFAIL), BigDecimal.ZERO);
        final BigDecimal transferAmount = incAmount.add(tfrpayAmount).add(productfailAmount).add(rpnAmount).add(trfFailAmount);
        results.put("pf", Quartet.with(chargingAmount,
                wdAmount,
                transferAmount,
                buyAmount.add(tfrAmount)));

        renderAjaxSuccess(results);
    }


    public void item() {
        final int pk_id = getParaToInt(0, 0);
        if (pk_id > 0) {
            CheckAccount account = CheckAccount.dao.findById(pk_id);
            if (account == null) {
                renderNull();
                return;
            }
            String tradeNo = account.getStr("outerorderno");
            Order order = Order.dao.findByOrdernoSingle(tradeNo);
            setAttr("self_order", order);
            setAttr("bank_order", account);
        } else {
            renderNull();
        }
    }


    public void export() {
        String time_q = getPara("time");
        String order_q = getPara("order");
        String type_q = getPara("type");

        StringBuilder whereSql = new StringBuilder();
        List<Object> params = Lists.newArrayList();

        if (!Strings.isNullOrEmpty(time_q)) {
            time_q = StringUtils.replace(time_q, StringPool.SLASH, StringPool.EMPTY);
            final String[] times = time_q.split(DATE_SPLIT);
            whereSql.append(" AND rca.transdate BETWEEN ? AND ? ");
            params.add(times[0]);
            params.add(times[1]);
        } else {
            whereSql.append(" AND rca.transdate BETWEEN ? AND ? ");
            params.add(DateTime.now().plusWeeks(-1).toString(DateFormatter.YYYYMMDD));
            params.add(DateTime.now().toString(DateFormatter.YYYYMMDD));
        }
        if (!Strings.isNullOrEmpty(order_q)) {
            whereSql.append(" AND rca.outerorderno LIKE ? ");
            params.add(DaoKit.like(order_q));
        }
        if (!Strings.isNullOrEmpty(type_q)) {
            whereSql.append(" AND rca.ordertype = ? ");
            params.add(type_q);
        }

        List<CheckAccount> checkAccounts = CheckAccount.dao.find(SqlKit.sql("checkaccount.findByExceptor") + whereSql.toString(), params.toArray());

        int ordertype, orderstatus;
        for (CheckAccount checkAccount : checkAccounts) {
            checkAccount.put("bankorderstatus", ORDER_STATUS.get(TypeKit.getInt(checkAccount, "bankorderstatus")));

            orderstatus = TypeKit.getInt(checkAccount, "orderstatus");
            checkAccount.put("orderstatus", orderstatus == 0 ? StringPool.EMPTY : ORDER_STATUS.get(orderstatus));
            ordertype = TypeKit.getInt(checkAccount, "ordertype");
            checkAccount.put("ordertype", ordertype == 0 ? StringPool.EMPTY : ORDER_TYPES.get(ordertype));
        }
        Map<String, Object> beans = Maps.newHashMap();
        beans.put("item", checkAccounts);
        beans.put("export_time", DateTime.now().toString(DateFormatter.DATE_TIME_PATTERN_YYYY_MM_DD_HH_MM));
        beans.put("export_user", Securitys.getLogin().getName());
        render(JxlsRender.me(ReportTplPathKit.getBank_check_account()).beans(beans).filename("银行对账单.xlsx"));

    }
}